import React, { useState } from "react";
import { Card, Divider, Upload, Button, Radio, message, Space } from "antd";
import {
  UploadOutlined,
  SwapOutlined,
  DownloadOutlined,
} from "@ant-design/icons";
import type { UploadFile, RadioChangeEvent } from "antd";
import "react-image-crop/dist/ReactCrop.css";
import ToolTitle from "@/components/ToolTitle";
import { imgToolsData } from "@/components/ToolsData";

interface ImageItem {
  originFile: File;
  url: string;
  width: number;
  height: number;
}

type SpliceDirection = "horizontal" | "vertical";

const ImageSplicing: React.FC = () => {
  const [imageList, setImageList] = useState<ImageItem[]>([]);
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [splicedImageUrl, setSplicedImageUrl] = useState<string | null>(null);
  const [spliceDirection, setSpliceDirection] =
    useState<SpliceDirection>("horizontal");
  const [loading, setLoading] = useState(false);

  // 处理文件上传
  const handleFileChange = async ({ fileList: newFileList }: any) => {
    setFileList(newFileList);

    // 清除已拼接的图片
    setSplicedImageUrl(null);

    // 处理新上传的图片
    const newImageList: ImageItem[] = [];

    for (const file of newFileList) {
      if (file.originFileObj) {
        const url = URL.createObjectURL(file.originFileObj);

        // 获取图片尺寸
        const dimensions = await getImageDimensions(url);

        newImageList.push({
          originFile: file.originFileObj,
          url,
          width: dimensions.width,
          height: dimensions.height,
        });
      }
    }

    setImageList(newImageList);
  };

  // 获取图片尺寸
  const getImageDimensions = (
    url: string
  ): Promise<{ width: number; height: number }> => {
    return new Promise((resolve) => {
      const img = new Image();
      img.onload = () => {
        resolve({
          width: img.width,
          height: img.height,
        });
      };
      img.src = url;
    });
  };

  // 处理拼接方向变更
  const handleDirectionChange = (e: RadioChangeEvent) => {
    setSpliceDirection(e.target.value);
  };

  // 执行图片拼接
  const handleSpliceImages = async () => {
    if (imageList.length < 2) {
      message.warning("请至少上传两张图片进行拼接");
      return;
    }

    setLoading(true);

    try {
      // 创建画布
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");

      if (!ctx) {
        message.error("创建画布失败");
        return;
      }

      // 计算画布尺寸
      let totalWidth = 0;
      let totalHeight = 0;
      let maxWidth = 0;
      let maxHeight = 0;

      if (spliceDirection === "horizontal") {
        // 水平拼接：宽度相加，高度取最大值
        totalWidth = imageList.reduce((sum, img) => sum + img.width, 0);
        maxHeight = Math.max(...imageList.map((img) => img.height));
        canvas.width = totalWidth;
        canvas.height = maxHeight;
      } else {
        // 垂直拼接：高度相加，宽度取最大值
        totalHeight = imageList.reduce((sum, img) => sum + img.height, 0);
        maxWidth = Math.max(...imageList.map((img) => img.width));
        canvas.width = maxWidth;
        canvas.height = totalHeight;
      }

      // 绘制图片
      let currentX = 0;
      let currentY = 0;

      for (const image of imageList) {
        const img = new Image();
        img.src = image.url;

        await new Promise<void>((resolve) => {
          img.onload = () => {
            ctx.drawImage(img, currentX, currentY);

            if (spliceDirection === "horizontal") {
              currentX += image.width;
            } else {
              currentY += image.height;
            }

            resolve();
          };
        });
      }

      // 生成拼接后的图片URL
      const splicedUrl = canvas.toDataURL("image/png");
      setSplicedImageUrl(splicedUrl);

      message.success("图片拼接成功");
    } catch (error) {
      console.error("拼接图片出错:", error);
      message.error("图片拼接失败");
    } finally {
      setLoading(false);
    }
  };

  // 下载拼接后的图片
  const handleDownload = () => {
    if (!splicedImageUrl) return;

    const link = document.createElement("a");
    link.href = splicedImageUrl;
    link.download = `spliced-image-${Date.now()}.png`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  return (
    <Card>
      <ToolTitle
        title={
          imgToolsData.find((item) => item.title === "图片拼接")?.title || ""
        }
        description={
          imgToolsData.find((item) => item.title === "图片拼接")?.description ||
          ""
        }
      />

      <Divider />

      <div className="flex flex-col gap-6">
        {/* 图片上传区域 */}
        <div className="mb-4">
          <div className="mb-2 font-medium">上传图片</div>
          <Upload
            listType="picture-card"
            fileList={fileList}
            onChange={handleFileChange}
            beforeUpload={() => false}
            multiple
            accept="image/*"
          >
            <div className="flex flex-col items-center">
              <UploadOutlined className="text-lg" />
              <div className="mt-1">上传</div>
            </div>
          </Upload>
        </div>

        {/* 拼接配置 */}
        <div className="mb-4">
          <div className="mb-2 font-medium">拼接设置</div>
          <Radio.Group value={spliceDirection} onChange={handleDirectionChange}>
            <Radio.Button value="horizontal">水平拼接</Radio.Button>
            <Radio.Button value="vertical">垂直拼接</Radio.Button>
          </Radio.Group>
        </div>

        {/* 操作按钮 */}
        <div className="mb-4">
          <Space>
            <Button
              type="primary"
              icon={<SwapOutlined />}
              onClick={handleSpliceImages}
              loading={loading}
              disabled={imageList.length < 2}
            >
              开始拼接
            </Button>

            <Button
              icon={<DownloadOutlined />}
              onClick={handleDownload}
              disabled={!splicedImageUrl}
            >
              下载图片
            </Button>
          </Space>
        </div>

        {/* 拼接结果 */}
        {splicedImageUrl && (
          <div className="mt-4">
            <div className="mb-2 font-medium">拼接结果</div>
            <div className="border border-gray-200 p-2 rounded">
              <img
                src={splicedImageUrl}
                alt="拼接结果"
                className="max-w-full object-contain"
              />
            </div>
          </div>
        )}
      </div>
    </Card>
  );
};

export default ImageSplicing;
